package piwan;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

public class World {
	public Region getRegionAt( Vector2 pt ) {
		for(Region r: regs)
			if(r.contains(pt))
				return r;
		return null;
	}
	
	public void readFromMap( String fileName ) throws IOException {
		Scanner file = new Scanner( new File(fileName) );
		readTypes(file);
		readRscs(file);
		readVerts(file);
		readRegs(file);
		addAdjacents();
	}
	
	private void readTypes( Scanner file ) throws IOException {
		int n = file.nextInt();
		types = new RegionType[n];
		for(int i=0; i<n; ++i) {
			types[i] = new RegionType();
			types[i].readText(file);
			types[i].setId(i);
		}
	}
	
	private void readRscs( Scanner file ) throws IOException {
		int n = file.nextInt();
		rscs = new ResourceType[n];
		for(int i=0; i<n; ++i) {
			rscs[i] = new ResourceType();
			rscs[i].readText(file);
			rscs[i].setId(i);
		}	
	}
	
	private void readVerts( Scanner file ) throws IOException {
		int n = file.nextInt();
		verts = new Vector2[n];
		for(int i=0; i<n; ++i)
			verts[i] = new Vector2(file.nextDouble(),file.nextDouble());
	}
	
	private void readRegs( Scanner file ) throws IOException {
		int n = file.nextInt();
		regs = new Region[n];
		for(int i=0; i<n; ++i) {
			regs[i] = new Region();
			regs[i].setId(i);
		}
		
		for(Region r: regs)
			r.readFromMap(file, this);
	}
	
	
	@SuppressWarnings("unchecked")
	private void addAdjacents() {
		ArrayList<Region>[] graph = new ArrayList[regs.length];
		for(int i=0;i<regs.length;++i)
			graph[i] = new ArrayList<Region>();
		
		boolean areAdjacent;
		for(int i1=0; i1<regs.length; ++i1) {
			Region r1 = regs[i1];
			for(int i2=i1+1; i2<regs.length; ++i2) {
				Region r2 = regs[i2];
				areAdjacent = false;
				for(Polygon p1: r1.getPolygons()) {
					for(Polygon p2: r2.getPolygons()) {
						for(Vector2 v1: p1.getVertices()) {
							for(Vector2 v2: p2.getVertices())
								if(v1==v2) {
									areAdjacent=true;
									graph[r1.getId()].add(r2);
									graph[r2.getId()].add(r1);
									break;
								}
							if(areAdjacent) break;
						}
						if(areAdjacent) break;
					}
					if(areAdjacent) break;
				}
			}
		}
		
		for(Region r:regs)
			r.addAdjacent(graph[r.getId()]); 
	}
	
	public Region[]			getRegions() { return regs; }
	public Vector2[]		getVertices() { return verts; }
	public RegionType[]		getRegionTypes() { return types; }
	public ResourceType[]	getResourceTypes() { return rscs; }
	public Region			getRegion(int i) { return regs[i]; }
	public Vector2			getVertex(int i) { return verts[i]; }
	public int				getRegionCount() { return regs.length; }
	public int				getRegionTypeCount() { return types.length; }
	public int				getResourceTypeCount() { return rscs.length; }
	public ResourceType		getResourceType(int i) { return rscs[i]; }
	public RegionType		getRegionType(int i) { return types[i]; }
	
	private Vector2[]		verts	= null;
	private Region[]		regs	= null;
	private RegionType[] 	types	= null;
	private ResourceType[]	rscs	= null;
}
